package com.gmcloud.common.oss.endpoint;

import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectSummary;
import com.gmcloud.common.oss.service.OssTemplate;
import com.gmcloud.common.utils.R;
import net.dreamlu.mica.auto.annotation.AutoIgnore;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zl.sir
 * @since  2022/9/19 15:00
 * @BelongsProject gm-cloud
 * @BelongsPackage com.gm.plugin.oss.endpoint
 * @description oss web
 */
@AutoIgnore
@RestController
@RequestMapping("/oss")
public class OssEndpoint {

    private final OssTemplate ossTemplate;

    public OssEndpoint(OssTemplate ossTemplate) {
        this.ossTemplate = ossTemplate;
    }


    /**
     * Bucket Endpoints  创建桶
     */
    @PostMapping("/bucket/{bucketName}")
    public R<Bucket> createBucket(@PathVariable String bucketName) throws Exception {

        ossTemplate.createBucket(bucketName);
        return R.ok(ossTemplate.getBucket(bucketName).orElseThrow());

    }

    /**
     * 获取所有桶名称
     *
     * @return 集合
     * @throws Exception 异常
     */
    @GetMapping("/buckets")
    public R<List<Bucket>> getBuckets() throws Exception {
        return R.ok(ossTemplate.getAllBuckets());
    }


    /**
     * 根据桶名称获取桶
     *
     * @param bucketName 桶名称
     * @return 桶
     * @throws Exception 异常
     */
    @GetMapping("/bucket/{bucketName}")
    public R<Bucket> getBucket(@PathVariable String bucketName) throws Exception {
        return R.ok(ossTemplate.getBucket(bucketName)
                .orElseThrow(() -> new IllegalArgumentException("Bucket Name not found!")));
    }

    /**
     * 根据桶名删除
     *
     * @param bucketName 桶名称
     * @throws Exception 异常
     */
    @DeleteMapping("/bucket/{bucketName}")
    @ResponseStatus(HttpStatus.ACCEPTED)
    public void deleteBucket(@PathVariable String bucketName) throws Exception {
        ossTemplate.removeBucket(bucketName);
    }

    /**
     * 上传文件
     *
     * @param multipartFile 文件
     * @param bucketName    桶名
     * @return 文件信息对象
     * @throws Exception 异常
     */
    @PostMapping("/object/{bucketName}")
    public R<S3Object> createObject(@RequestParam("file") MultipartFile multipartFile, @PathVariable String bucketName) throws Exception {
        String name = multipartFile.getOriginalFilename();
        ossTemplate.putObject(bucketName, name, multipartFile.getInputStream(), multipartFile.getSize(), multipartFile.getContentType());
        return R.ok(ossTemplate.getObjectInfo(bucketName, name));

    }

    /**
     * 上传文件自定义文件名
     *
     * @param file       文件
     * @param bucketName 桶名
     * @param fileName   文件名  文件名采用uuid,避免原始文件名中带"-"符号导致下载的时候解析出现异常
     * @return 文件信息
     * @throws Exception 异常
     */
    @PostMapping("/object/{bucketName}/{fileName}")
    public R<S3Object> createObject(@RequestParam("file") MultipartFile file, @PathVariable String bucketName,
                                    @PathVariable String fileName) throws Exception {
        ossTemplate.putObject(bucketName, fileName, file.getInputStream(), file.getSize(),
                file.getContentType());
        return R.ok(ossTemplate.getObjectInfo(bucketName, fileName));

    }

    /**
     * 过滤桶
     *
     * @param bucketName 桶名称
     * @param prefix     文件名前缀
     * @return 文件集合
     */
    @GetMapping("/object/{bucketName}/{prefix}")
    public R<List<S3ObjectSummary>> filterObject(@PathVariable String bucketName, @PathVariable String prefix) {

        return R.ok(ossTemplate.getAllObjectsByPrefix(bucketName, prefix));

    }

    /**
     * 获取文件外链，只用于下载
     *
     * @param bucketName 桶名称
     * @param fileName   文件名
     * @param expires    过期时间，单位分钟,请注意该值必须小于7天
     * @return map
     * @throws Exception 异常
     */
    @GetMapping("/object/{bucketName}/{fileName}/{expires}")
    public R<Map<String, Object>> getObject(@PathVariable String bucketName, @PathVariable String fileName,
                                            @PathVariable Integer expires) throws Exception {
        Map<String, Object> responseBody = new HashMap<>(8);
        // Put Object info
        responseBody.put("bucket", bucketName);
        responseBody.put("fileName", fileName);
        responseBody.put("url", ossTemplate.getObjectURL(bucketName, fileName, expires));
        responseBody.put("expires", expires);
        return R.ok(responseBody);
    }

    /**
     * 删除文件
     *
     * @param bucketName 桶名称
     * @param fileName   文件名
     * @throws Exception 异常
     */
    @ResponseStatus(HttpStatus.ACCEPTED)
    @DeleteMapping("/object/{bucketName}/{fileName}/")
    public void deleteObject(@PathVariable String bucketName, @PathVariable String fileName) throws Exception {
        ossTemplate.removeObject(bucketName, fileName);
    }

}
